﻿// Serotonin -- easy-to-use image filters application
// https://code.google.com/p/serotonin/
//
// Copyright © Frank Nagl, 2012-2013
// admin@franknagl.de
//
namespace Serotonin.Controls
{
    using Helper;
    using System;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.Globalization;
    using System.IO;
    using System.Text.RegularExpressions;
    using System.Windows.Forms;

    /// <summary> Form for setting image save properties. </summary>
    public partial class SaveImageDialogForm : Form
    {
        private enum Formats
        {
            JPEG24,
            PNG1,
            PNG8,
            PNG24,
            PNG32Alpha,
            BMP1,
            BMP8,
            BMP24            
        }        

        private Formats format;
        private bool isExit;
        private int jpegQuality;
        private Processor processor;
        private Color transparencyColor;
        private readonly FolderBrowserDialog folderBrowserDialog;

        /// <summary>
        /// Initializes a new instance of the <see cref="SaveImageDialogForm" /> 
        /// class.
        /// </summary>
        public SaveImageDialogForm()
        {
            InitializeComponent();
            jpegQuality = trBarQuality.Value;
            transparencyColor = btnTransparencyColor.BackColor;
            folderBrowserDialog = new FolderBrowserDialog
            {
                RootFolder = Environment.SpecialFolder.Desktop
            };

            string desktop = 
                Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            folderBrowserDialog.SelectedPath = desktop;
            SetLinkPathText(desktop);
        }

        /// <summary>
        /// Sets the processor instance and adapts the selected path of 
        /// FolderBrowserDialog.
        /// </summary>
        /// <param name="p">The processor of Serotonin.</param>
        public void SetProcessor(Processor p)
        {
            processor = p;
            string path = Directory.GetParent(p.ImageFilename).ToString();
            folderBrowserDialog.SelectedPath = path;
            SetLinkPathText(path);                       
        }

        /// <summary>
        /// Closes and not hides the form.
        /// </summary>
        public void CloseReally()
        {
            isExit = true;
            Close();
        }

        #region radio button checked changed events
        private void RbJpeg24CheckedChanged(object sender, EventArgs e)
        {
            trBarQuality.Enabled = rbJpeg24.Checked;
            tbQuality.Enabled = rbJpeg24.Checked;
            lbQuality.Enabled = rbJpeg24.Checked;
            lbPercent.Enabled = rbJpeg24.Checked;

            if (rbJpeg24.Checked)
            {
                format = Formats.JPEG24;
                lbImageFormat.Text = ".jpg";
                UncheckOtherRadioButtons(rbJpeg24);
            }
        }

        private void RbPng1BitCheckedChanged(object sender, EventArgs e)
        {
            if (rbPng1.Checked)
            {
                format = Formats.PNG1;
                lbImageFormat.Text = ".png";
                UncheckOtherRadioButtons(rbPng1);
            }
        }

        private void RbPng8BitCheckedChanged(object sender, EventArgs e)
        {
            if (rbPng8.Checked)
            {
                format = Formats.PNG8;
                lbImageFormat.Text = ".png";
                UncheckOtherRadioButtons(rbPng8);
            }
        }

        private void RbPng24CheckedChanged(object sender, EventArgs e)
        {
            if (rbPng24.Checked)
            {
                format = Formats.PNG24;
                lbImageFormat.Text = ".png";
                UncheckOtherRadioButtons(rbPng24);
            }
        }

        private void RbPng32CheckedChanged(object sender, EventArgs e)
        {
            lbTransparencyColor.Enabled = rbPng32.Checked;
            btnTransparencyColor.Enabled = rbPng32.Checked;

            if (rbPng32.Checked)
            {
                format = Formats.PNG32Alpha;
                lbImageFormat.Text = ".png";
                UncheckOtherRadioButtons(rbPng32);
            }
        }

        private void RbBmp1CheckedChanged(object sender, EventArgs e)
        {
            if (rbBmp1.Checked)
            {
                format = Formats.BMP1;
                lbImageFormat.Text = ".bmp";
                UncheckOtherRadioButtons(rbBmp1);
            }
        }

        private void RbBmp8CheckedChanged(object sender, EventArgs e)
        {
            if (rbBmp8.Checked)
            {
                format = Formats.BMP8;
                lbImageFormat.Text = ".bmp";
                UncheckOtherRadioButtons(rbBmp8);
            }
        }

        private void RbBmp24CheckedChanged(object sender, EventArgs e)
        {
            if (rbBmp24.Checked)
            {
                format = Formats.BMP24;
                lbImageFormat.Text = ".bmp";
                UncheckOtherRadioButtons(rbBmp24);
            }
        }

        #endregion radio button checked changed events

        private void BtnTransparencyColorClick(object sender, EventArgs e)
        {
            ColorDialog dialog = new ColorDialog
            {
                Color = transparencyColor, 
                AllowFullOpen = true
            };

            if (dialog.ShowDialog(this) == DialogResult.OK)
            {
                transparencyColor = dialog.Color;
                btnTransparencyColor.BackColor = dialog.Color;
            }
        }

        private void BtnOkClick(object sender, EventArgs e)
        {
            // string temp = "Oioioi.";
            if (tbFilename.Text.Length == 0)
            {
                MessageBox.Show(this, Program.L.Text[59], Program.L.Text[60]);
                return;
            }

            Bitmap b;
            tbFilename.Text = Regex.Replace(tbFilename.Text, @"[\\/:?*^""<>|]", "_");
            string workingImageFilename =
                folderBrowserDialog.SelectedPath + "\\" + tbFilename.Text +
                lbImageFormat.Text;

            if (File.Exists(workingImageFilename))
            {
                if (MessageBox.Show(
                    this, Program.L.Text[61], Program.L.Text[62], 
                    MessageBoxButtons.YesNo) == DialogResult.No)
                {
                    return;
                }
            }

            switch (format)
            {
                case Formats.JPEG24:
                    //Store the original EXIF infos
                    PropertyItem[] items = processor.OriginalImage.PropertyItems;
                    //Before saving, set the original EXIF infos                
                    foreach (PropertyItem item in items)
                    {
                        processor.WorkingImage.SetPropertyItem(item);
                    }

                    Metadata.SetJpgTag(processor.WorkingImage, 
                        Metadata.JPG_USER_COMMENT /* "User Comment" */, 
                        processor.FilterText);

                    JpegEncoder.SaveJpeg(workingImageFilename,
                                        processor.WorkingImage, jpegQuality);
                    break;
                case Formats.PNG1:
                    b = BitmapConverter.To1Bpp(processor.WorkingImage);
                    b.Save(workingImageFilename, ImageFormat.Png);
                    // b.Dispose();
                    Metadata.SetPngTag(
                        workingImageFilename, processor.FilterText, Metadata.PNG_USER_COMMENT);
                    break;
                case Formats.PNG8:
                    b = BitmapConverter.To8Bpp(processor.WorkingImage);
                    b.Save(workingImageFilename, ImageFormat.Png);
                    // b.Dispose();
                    Metadata.SetPngTag(
                        workingImageFilename, processor.FilterText, Metadata.PNG_USER_COMMENT);
                    break;
                case Formats.PNG24:
                    b = BitmapConverter.To24Bpp(processor.WorkingImage);                    
                    b.Save(workingImageFilename, ImageFormat.Png);
                    // b.Dispose();
                    Metadata.SetPngTag(
                        workingImageFilename, processor.FilterText, Metadata.PNG_USER_COMMENT);
                    //string s = Metadata.GetPngTag(
                    //    workingImageFilename, Metadata.PNG_USER_COMMENT);
                    //MessageBox.Show(s);
                    break;
                case Formats.PNG32Alpha:
                    b = processor.WorkingImage.Clone() as Bitmap;
                    // ReSharper disable PossibleNullReferenceException
                    b.MakeTransparent(transparencyColor);
                    // ReSharper restore PossibleNullReferenceException
                    b.Save(
                        workingImageFilename, ImageFormat.Png);
                    Metadata.SetPngTag(
                        workingImageFilename, processor.FilterText, Metadata.PNG_USER_COMMENT);
                    break;
                case Formats.BMP1:
                    b = BitmapConverter.To1Bpp(processor.WorkingImage);
                    b.Save(workingImageFilename, ImageFormat.Bmp);
                    break;
                case Formats.BMP8:
                    b = BitmapConverter.To8Bpp(processor.WorkingImage);
                    b.Save(workingImageFilename, ImageFormat.Bmp);
                    break;
                case Formats.BMP24:
                    b = BitmapConverter.To24Bpp(processor.WorkingImage);
                    b.Save(workingImageFilename, ImageFormat.Bmp);
                    // b.Dispose();
                    break;
            }

            Hide();
        }

        private void BtnCancelClick(object sender, EventArgs e)
        {
            Hide();
        }

        private void TbFilenameKeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Return)
            {
                BtnOkClick(sender, e);
            }
        }

        private void TrBarQualityValueChanged(object sender, EventArgs e)
        {
            jpegQuality = trBarQuality.Value;
            tbQuality.Text = jpegQuality.ToString(CultureInfo.InvariantCulture);
        }

        private void LinkPathLinkClicked(
            object sender, LinkLabelLinkClickedEventArgs e)
        {
            if (folderBrowserDialog.ShowDialog(this) == DialogResult.OK)
            {
                SetLinkPathText(folderBrowserDialog.SelectedPath);
            }
        }

        private void SaveImageDialogFormFormClosing(object sender, FormClosingEventArgs e)
        {
            if (isExit)
            {
                return;
            }
            e.Cancel = true;
            Hide();
        }

        private void SetLinkPathText(string path)
        {
            const int maxLengthOfLinkPath = 33;
            if (path.Length > maxLengthOfLinkPath)
            {
                int start = path.Length - maxLengthOfLinkPath + 3;
                linkPath.Text = string.Format("...{0}", path.Substring(start));

            }
            else
            {
                linkPath.Text = path;
            }            
        }

        private void UncheckOtherRadioButtons(RadioButton rb)
        {
            if (rb.Name != rbJpeg24.Name) rbJpeg24.Checked = false;
            if (rb.Name != rbPng8.Name) rbPng8.Checked = false;
            if (rb.Name != rbPng24.Name) rbPng24.Checked = false;
            if (rb.Name != rbPng32.Name) rbPng32.Checked = false;
            if (rb.Name != rbBmp24.Name) rbBmp24.Checked = false;
            if (rb.Name != rbBmp1.Name) rbBmp1.Checked = false;           
        }
    }
}
